package com.dog.basics.service.mtkj.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dog.basics.bean.dto.admin.mtkj.UserAddrFromDto;
import com.dog.basics.bean.dto.api.mtkj.ApiUserAddrAddDto;
import com.dog.basics.bean.dto.api.mtkj.ApiUserAddrEditDto;
import com.dog.basics.bean.dto.api.mtkj.ApiUserAddrPageDto;
import com.dog.basics.bean.model.common.DogComPositioninfo;
import com.dog.basics.bean.model.common.DogUser;
import com.dog.basics.bean.model.mtkj.MtUserAddr;
import com.dog.basics.bean.vo.admin.mtkj.UserAddrFromVo;
import com.dog.basics.bean.vo.api.mtkj.ApiUserAddrVo;
import com.dog.basics.common.util.PageParam;
import com.dog.basics.dao.common.DogComPositioninfoMapper;
import com.dog.basics.dao.common.DogUserMapper;
import com.dog.basics.dao.mtkj.MtUserAddrMapper;
import com.dog.basics.security.util.SecurityUtils;
import com.dog.basics.service.mtkj.IMtUserAddrService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户配送地址 服务实现类
 * </p>
 *
 * @author wph
 * @since 2020-11-09
 */
@Service
@AllArgsConstructor
public class MtUserAddrServiceImpl extends ServiceImpl<MtUserAddrMapper, MtUserAddr> implements IMtUserAddrService {

    private final DogComPositioninfoMapper positioninfoMapper;
    private final DogUserMapper userMapper;

    /**
     * 根据用户id查询当前用户下所有 状态为有效的地址
     *
     * @param
     * @return
     * @author hangdy
     */
    @Override
    public IPage<ApiUserAddrVo> findByUserId(PageParam page, ApiUserAddrPageDto dto) {
        IPage iPage = this.page(page, Wrappers.<MtUserAddr>lambdaQuery()
                .eq(MtUserAddr::getUserId, dto.getUserId())
                .eq(ObjectUtil.isNotNull(dto.getCommonAddr()),MtUserAddr::getCommonAddr, dto.getCommonAddr())
                .eq(MtUserAddr::getStatus, 1));
        List<MtUserAddr> userAddrVoList = iPage.getRecords();
        iPage.setRecords(userAddrVoList.stream().map(e -> BeanUtil.toBean(e, ApiUserAddrVo.class)).collect(Collectors.toList()));

        return iPage;
    }

    /**
     * 设置默认地址： 查询以前设置默认的地址并修改成不默认
     * 查询出当前需要设置默认的地址并修改为默认
     *
     * @param id
     * @return
     * @author hangdy
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setDefault(Long id) {
        Long userId = SecurityUtils.getUser().getUserId();

        //查询当前需要设置成默认的地址并修改 start
        MtUserAddr defaultAddr = this.getById(id);
        Validator.validateNotNull(defaultAddr,"未找到对应地址");
        Validator.validateEqual(defaultAddr.getUserId(),userId,"数据错误");

        defaultAddr.setCommonAddr(1);
        //查询当前需要设置成默认的地址并修改 end
        //查询以前设置的默认地址并取消默认 start
        List<MtUserAddr> userAddrList = this.list(new QueryWrapper<MtUserAddr>().lambda()
                .eq(MtUserAddr::getUserId, userId)
                .eq(MtUserAddr::getCommonAddr, 1)
        );
        if (userAddrList.size() > 0) {

            userAddrList.stream().map(e -> e.setCommonAddr(0)).collect(Collectors.toList());
            Validator.validateTrue(this.updateBatchById(userAddrList), "取消当前默认地址失败");
        }
        //查询以前设置的默认地址并取消默认 end
        //保存当前默认地址
        Validator.validateTrue(this.updateById(defaultAddr), "设置默认地址失败");
        return Boolean.TRUE;
    }

    /**
     * 新增地址
     *      判断省 市 区 是否正确并保存地名
     *      判断是是否有默认地址并修改
     * @param userAddrAddDto
     * @return
     * @author hangdy
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveUserAddr(ApiUserAddrAddDto userAddrAddDto) {
        MtUserAddr userAddr = new MtUserAddr();
        BeanUtil.copyProperties(userAddrAddDto, userAddr);
        userAddr.setCreateTime(DateUtil.currentSeconds());
        userAddr.setUserId(SecurityUtils.getUser().getUserId());
        //设置正常
        userAddr.setStatus(1);
        //省
        userAddr.setProvince(getAreaName(userAddrAddDto.getProvinceId()));
        //市
        userAddr.setCity(getAreaName(userAddrAddDto.getCityId()));
        //区
        userAddr.setArea(getAreaName(userAddrAddDto.getAreaId()));

        //判断是否默认并检查是否已有默认地址 start
        if (ObjectUtil.equal(userAddrAddDto.getCommonAddr(), 1)) {
            //如果已有默认地址 修改为不默认
            List<MtUserAddr> userAddrList = this.list(Wrappers.<MtUserAddr>lambdaQuery()
                    .eq(MtUserAddr::getUserId, SecurityUtils.getUser().getUserId())
                    .eq(MtUserAddr::getCommonAddr, 1));
            if(ObjectUtil.isNotNull(userAddrList)){
                userAddrList.stream().map(e -> e.setCommonAddr(0)).collect(Collectors.toList());
            }

            Validator.validateTrue(this.updateBatchById(userAddrList), "取消已有默认地址失败");
        }
        //判断是否默认并检查是否已有默认地址 end

        Validator.validateTrue(this.saveOrUpdate(userAddr), "新增地址失败");
        return Boolean.TRUE;
    }

    /**
     * 修改地址
     *      判断省 市 区 是否正确并保存地名
     *      判断是是否有默认地址并修改
     * @param userAddrEditDto
     * @return
     * @author hangdy
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editUserAddr(ApiUserAddrEditDto userAddrEditDto) {
        MtUserAddr userAddr = this.getById(userAddrEditDto.getId());
        Validator.validateNotNull(userAddr, "未找到地址信息");
        BeanUtil.copyProperties(userAddrEditDto, userAddr);
        userAddr.setUpdateTime(DateUtil.currentSeconds());

        //省
        userAddr.setProvince(getAreaName(userAddrEditDto.getProvinceId()));
        //市
        userAddr.setCity(getAreaName(userAddrEditDto.getCityId()));
        //区
        userAddr.setArea(getAreaName(userAddrEditDto.getAreaId()));

        //判断是否默认并检查是否已有默认地址 start
        if (ObjectUtil.equal(userAddrEditDto.getCommonAddr(), 1)) {
            //如果已有默认地址 修改为不默认
            List<MtUserAddr> userAddrList = this.list(Wrappers.<MtUserAddr>lambdaQuery()
                    .eq(MtUserAddr::getUserId, SecurityUtils.getUser().getUserId())
                    .eq(MtUserAddr::getCommonAddr, 1));

            if(ObjectUtil.isNotNull(userAddrList)){
                userAddrList.stream().map(e -> e.setCommonAddr(0)).collect(Collectors.toList());
            }

            Validator.validateTrue(this.updateBatchById(userAddrList), "取消已有默认地址失败");
        }
        //判断是否默认并检查是否已有默认地址 end

        Validator.validateTrue(this.updateById(userAddr), "修改地址失败");
        return Boolean.TRUE;
    }

    /**
     * 删除用户地址
     *      判断是否是自己的地址，如果是自己的地址才允许删除
     * @param id
     * @return
     * @author hangdy
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUserAddr(Long id) {
        MtUserAddr userAddr = this.getById(id);
        Validator.validateNotNull(userAddr, "无此数据");
        Validator.validateEqual(userAddr.getUserId(),SecurityUtils.getUser().getUserId(),"无法删除");

        Validator.validateTrue(this.removeById(id), "删除数据失败");
        return Boolean.TRUE;
    }

    /**
     * 查询地区名称
     *
     * @param areaId
     * @return
     * @author hangdy
     */
    private String getAreaName(Long areaId) {

        DogComPositioninfo province = positioninfoMapper.selectById(areaId);
        Validator.validateNotNull(province, "未找到地区信息:" + areaId);
        return province.getAbbrName();

    }


    /**
     * admin服务
     *  查询用户地址
     * @param page
     * @return
     */
    @Override
    public IPage<UserAddrFromVo> findUserAddr(PageParam page , UserAddrFromDto fromDto) {

        IPage iPage = this.page(page, Wrappers.<MtUserAddr>lambdaQuery()
                .eq(ObjectUtil.isNotNull(fromDto.getMobile()),MtUserAddr::getMobile, fromDto.getMobile())
                .eq(ObjectUtil.isNotNull(fromDto.getStatus()),MtUserAddr::getStatus, 1)
                .eq(ObjectUtil.isNotNull(fromDto.getCommonAddr()),MtUserAddr::getCommonAddr, fromDto.getCommonAddr())
                .eq(ObjectUtil.isNotNull(fromDto.getPostCode()),MtUserAddr::getPostCode, fromDto.getPostCode())

                .like(ObjectUtil.isNotNull(fromDto.getReceiver()),MtUserAddr::getReceiver ,fromDto.getReceiver())
                .like(ObjectUtil.isNotNull(fromDto.getProvince()),MtUserAddr::getProvince ,fromDto.getProvince())
                .like(ObjectUtil.isNotNull(fromDto.getCity()),MtUserAddr::getCity ,fromDto.getCity())
                .like(ObjectUtil.isNotNull(fromDto.getArea()),MtUserAddr::getArea ,fromDto.getArea())
                .like(ObjectUtil.isNotNull(fromDto.getAddr()),MtUserAddr::getAddr ,fromDto.getAddr())

        );
        List<MtUserAddr> userAddrVoList = iPage.getRecords();
        iPage.setRecords(userAddrVoList.stream().map(e ->{
            UserAddrFromVo fromVo = BeanUtil.toBean(e, UserAddrFromVo.class);
            DogUser dogUser = userMapper.selectById(e.getUserId());
            if(dogUser != null){
                fromVo.setUserName(ObjectUtil.isNotNull(dogUser.getNickName()) ? dogUser.getNickName() : "");
            }

            return fromVo;
        }).collect(Collectors.toList()));

        return iPage;
    }

    /**
     * admin服务
     *  删除用户地址
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean adminDeleteUserAddr(Long id) {

        //2.判断数据是否存在
        MtUserAddr userAddr = this.getById(id);
        Validator.validateNotNull(userAddr, "无此数据");

        Validator.validateTrue(this.removeById(id), "删除数据失败");
        return Boolean.TRUE;
    }
}